[Windows 8] Update TextBox’s binding on TextChanged

Posted by Benjamin Roux on ASP.net Weblogs See other posts from ASP.net Weblogs or by Benjamin Roux
Published on Wed, 04 Jul 2012 00:08:33 GMT Indexed on 2012/07/04 3:16 UTC
Read the original article Hit count: 936

Filed under:
|
|
|

Since UpdateSourceTrigger is not available in WinRT we cannot update the text’s binding of a TextBox at will (or at least not easily) especially when using MVVM (I surely don’t want to write behind-code to do that in each of my apps !).

Since this kind of demand is frequent (for example to disable of button if the TextBox is empty) I decided to create some attached properties to to simulate this missing behavior.

namespace Indeed.Controls
{
    public static class TextBoxEx
    {
        public static string GetRealTimeText(TextBox obj)
        {
            return (string)obj.GetValue(RealTimeTextProperty);
        }

        public static void SetRealTimeText(TextBox obj, string value)
        {
            obj.SetValue(RealTimeTextProperty, value);
        }

        public static readonly DependencyProperty RealTimeTextProperty =
            DependencyProperty.RegisterAttached("RealTimeText", typeof(string), typeof(TextBoxEx), null);

        public static bool GetIsAutoUpdate(TextBox obj)
        {
            return (bool)obj.GetValue(IsAutoUpdateProperty);
        }

        public static void SetIsAutoUpdate(TextBox obj, bool value)
        {
            obj.SetValue(IsAutoUpdateProperty, value);
        }

        public static readonly DependencyProperty IsAutoUpdateProperty =
            DependencyProperty.RegisterAttached("IsAutoUpdate", typeof(bool), typeof(TextBoxEx), new PropertyMetadata(false, OnIsAutoUpdateChanged));

        private static void OnIsAutoUpdateChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var value = (bool)e.NewValue;
            var textbox = (TextBox)sender;

            if (value)
            {
                Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventArgs>(
                              o => textbox.TextChanged += o,
                              o => textbox.TextChanged -= o)
                          .Do(_ => textbox.SetValue(TextBoxEx.RealTimeTextProperty, textbox.Text))
                          .Subscribe();
            }
        }
    }
}

The code is composed of two attached properties. The first one “RealTimeText” reflects the text in real time (updated after each TextChanged event). The second one is only used to enable the functionality.

To subscribe to the TextChanged event I used Reactive Extensions (Rx-Metro package in Nuget). If you’re not familiar with this framework just replace the code with a simple:

textbox.TextChanged += textbox.SetValue(TextBoxEx.RealTimeTextProperty, textbox.Text);

To use these attached properties, it’s fairly simple

<TextBox Text="{Binding Path=MyProperty, Mode=TwoWay}" ic:TextBoxEx.IsAutoUpdate="True" ic:TextBoxEx.RealTimeText="{Binding Path=MyProperty, Mode=TwoWay}" />

Just make sure to create a binding (in TwoWay) for both Text and RealTimeText.

Hope this helps !

© ASP.net Weblogs or respective owner

Related posts about .NET

Related posts about Microsoft